package com.finance.rule.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.finance.base.constant.BaseConstants;
import com.finance.base.enums.*;
import com.finance.base.exception.BaseException;
import com.finance.framework.controller.BaseController;
import com.finance.framework.controller.Result;
import com.finance.framework.file.FileUtils;
import com.finance.framework.lang.BeanUtils;
import com.finance.framework.lang.Page;
import com.finance.framework.lang.PageResultBO;
import com.finance.rule.bean.pojo.SettlementRegion;
import com.finance.rule.bean.pojo.ValueRange;
import com.finance.rule.bean.pojo.WeightRangeList;
import com.finance.rule.bean.pojo.WeightRangeRule;
import com.finance.rule.export.WeightRangeImportTemplateBean;
import com.finance.rule.export.WeightRangeParse;
import com.finance.rule.request.WeightRangeImportReq;
import com.finance.rule.request.WeightRangeListReq;
import com.finance.rule.request.WeightRangeReq;
import com.finance.rule.service.ISettingLogService;
import com.finance.rule.service.ISettlementRegionService;
import com.finance.rule.service.IWeightRangeService;
import com.finance.system.bean.pojo.Organization;
import com.finance.system.bean.pojo.Supplier;
import com.finance.system.bean.pojo.User;
import com.finance.system.service.IOrganizationService;
import com.finance.system.service.ISupplierService;
import com.finance.util.export.ExportBuilder;
import com.finance.util.export.ExportFactory;
import com.finance.util.export.ImportUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.util.*;

/**
 * 重量区间管理
 */
@Controller
@RequestMapping("/rule/weight")
public class WeightRangeController extends BaseController {

    @Resource
    private IWeightRangeService weightRangeService;
    @Resource
    private IOrganizationService organizationService;
    @Resource
    private ISupplierService supplierService;
    @Resource
    private ISettlementRegionService settlementRegionService;
    @Resource
    private ISettingLogService settingLogService;
    private ObjectMapper objectMapper = new ObjectMapper();


    @RequestMapping("/index.htm")
    public String index() {
        return "rule/weight/index";
    }

    @RequestMapping("/list")
    public Result list(WeightRangeListReq form) {
        Page page = Page.getInstance(form);
        WeightRangeList list = new WeightRangeList();
        list.setDirection(form.getDirection());
        list.setSupplierName(form.getSupplierName());
        page.setParams(list);
        PageResultBO<WeightRangeRule> resultBO = weightRangeService.listByPage(page);
        return getSuccessResult(resultBO);
    }

    @RequestMapping("/listorgs")
    public Result list(String code) {
        List<Organization> organizations = organizationService.listAll();
        if (CollectionUtils.isNotEmpty(organizations) && StringUtils.isNotEmpty(code)) {
            for (Organization organization : organizations) {
                if (code.equals(organization.getOrgCode())) {
                    organization.setSelected(true);
                }
            }
        }
        return getSuccessResult(organizations);
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public Result add(@Valid WeightRangeReq form) throws BaseException {
        User user = getAuthUser();
        if (user == null) {
            throw new BaseException(BaseConstants.ERR_UNKONW_USER);
        }
        WeightRangeRule weightRange = convertWeightRangeRule(form);
        weightRange.setCreateUid(user.getId());
        weightRange.setState(StateEnum.Valid.getState());
        weightRangeService.add(weightRange);
        return getSuccessResult(true);
    }

    @RequestMapping(value = "/add.htm", method = RequestMethod.GET)
    public String add() {
        return "rule/weight/add";
    }

    @RequestMapping(value = "/update.htm", method = RequestMethod.GET)
    public String update(String id, HttpServletRequest request) {
        WeightRangeRule weightRange = weightRangeService.getById(Long.parseLong(id));
        request.setAttribute("weightRange", weightRange);
        return "rule/weight/update";
    }

    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public Result update(String id, @Valid WeightRangeReq form) throws ParseException {
        if (StringUtils.isEmpty(id)) {
            throw new BaseException(BaseConstants.ERR_INVALID_PARAMETER);
        }
        WeightRangeRule oldWeightRangeRule = weightRangeService.getById(Long.parseLong(id));
        if (null == oldWeightRangeRule) {
            throw new BaseException(BaseConstants.ERR_NON_EXISTENT);
        }
        User user = getAuthUser();
        oldWeightRangeRule.setSnapshot(null);
        String oldValue = null;
        try {
            oldValue = objectMapper.writeValueAsString(oldWeightRangeRule);
        } catch (JsonProcessingException e) {
            logger.error(e.getMessage(), e);
        }
        WeightRangeRule weightRangeRule = this.convertWeightRangeRule(form);
        weightRangeRule.setId(Long.parseLong(id));
        weightRangeRule.setSnapshot(oldValue);
        weightRangeService.update(weightRangeRule);
        settingLogService.addLog(user, OpearteEnum.UPDATE, TargetEnum.WEIGHT_RANGE_INFO, oldValue);
        return getSuccessResult(true);
    }

    private WeightRangeRule convertWeightRangeRule(WeightRangeReq form) {
        User user = getAuthUser();
        WeightRangeRule weightRangeRule = new WeightRangeRule();
        weightRangeRule.setValueRange(new ValueRange());

        SettlementRegion settlementRegion = new SettlementRegion();
        settlementRegion.setId(Long.parseLong(form.getRegionId()));

        weightRangeRule.setSettlementRegion(settlementRegion);
        weightRangeRule.setSupplier(new Supplier());
        weightRangeRule.getSupplier().setCode(form.getSupplierCode());
        try {
            BeanUtils.copyProperties(weightRangeRule, form);
            BeanUtils.copyProperties(weightRangeRule.getValueRange(), form);
        } catch (Exception e) {
            throw new BaseException(BaseConstants.ERR_COPYBEAN);
        }
        weightRangeRule.setUpdateUid(user.getId());
        try {
            weightRangeRule.setStartTime(form.convertStartTime());
            weightRangeRule.setEndTime(form.convertEndTime());
        } catch (ParseException e) {
            throw new BaseException(BaseConstants.ERR_INVALID_PARAMETER);
        }
        return weightRangeRule;
    }

    private WeightRangeRule convertWeightRangeRule(WeightRangeImportReq form) {

        WeightRangeRule weightRangeRule = new WeightRangeRule();
        weightRangeRule.setValueRange(new ValueRange());

        SettlementRegion settlementRegion = new SettlementRegion();
        settlementRegion.setId(Long.parseLong(form.getRegionId()));

        weightRangeRule.setSettlementRegion(settlementRegion);
        weightRangeRule.setSupplier(new Supplier());
        weightRangeRule.getSupplier().setCode(form.getSupplierCode());
        try {
            BeanUtils.copyProperties(weightRangeRule, form);
            BeanUtils.copyProperties(weightRangeRule.getValueRange(), form);
        } catch (Exception e) {
            throw new BaseException(BaseConstants.ERR_COPYBEAN);
        }
        User user = getAuthUser();
        weightRangeRule.setCreateUid(user.getId());
        try {
            weightRangeRule.setStartTime(form.convertStartTime());
            weightRangeRule.setEndTime(form.convertEndTime());
        } catch (ParseException e) {
            throw new BaseException(BaseConstants.ERR_INVALID_PARAMETER);
        }
        return weightRangeRule;
    }

    @RequestMapping("/del")
    public Result del(String ids) {
        if (StringUtils.isEmpty(ids)) {
            throw new BaseException(BaseConstants.ERR_INVALID_PARAMETER);
        }
        User user = getAuthUser();
        if (user == null) {
            throw new BaseException(BaseConstants.ERR_UNKONW_USER);
        }
        List<String> list = Arrays.asList(ids.split(","));
        if (list.size() > 0) {
            boolean ret = weightRangeService.del(user.getId().toString(), list);
            if (!ret) {
                return getSuccessResult(false);
            }
        }
        return getSuccessResult(true);
    }


    /**
     * 导入Excel模板下载
     */
    @RequestMapping("/exporttemplate")
    public void export(HttpServletResponse response) {
        try {
            ExportBuilder builder = new ExportBuilder
                    (WeightRangeImportTemplateBean.class,
                            new WeightRangeParse()
                    );
            ExportFactory factory = ExportFactory.getExportFactory(
                    builder);
            factory.setDataList(new ArrayList<WeightRangeRule>()).outPut(response);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);

        }
    }


    /**
     * 导入结果下载
     */
    @RequestMapping("/down")
    public void importData(String fileKey, HttpServletResponse response) {
        FileUtils.downFile(fileKey, response);
    }

    /**
     * 导入
     */
    @RequestMapping("/import")
    public Result importData(@RequestParam("file") CommonsMultipartFile[] multipartFile) {
        InputStream in = null;
        List<WeightRangeRule> errList = null;
        List<String> errMsg = null;
        int successNums = 0;
        int totalNums = 0;
        try {
            in = multipartFile[0].getInputStream();
            List<WeightRangeImportTemplateBean> list = ImportUtil.getImportFactory(in).outResult(WeightRangeImportTemplateBean.class);
            errList = new ArrayList<WeightRangeRule>();
            errMsg = new ArrayList<String>();
            if (list != null && list.size() > 0) {
                for (WeightRangeImportTemplateBean bean : list) {
                    WeightRangeImportReq form = new WeightRangeImportReq();
                    if (StringUtils.isNotBlank(bean.getSupplierCodeImport())) {
                        String supplierCode = supplierService.getCodeByName(bean.getSupplierCodeImport().trim());
                        if (StringUtils.isNotBlank(supplierCode)) {
                            form.setSupplierCode(supplierCode);
                        }
                    }
                    if (StringUtils.isNotBlank(bean.getDirectionImport())) {
                        String direction = bean.getDirectionImport();
                        if ("配送".equals(direction)) {
                            form.setDirection(String.valueOf(DirectionEnum.SEND.getValue()));
                        } else if ("上门换".equals(direction)) {
                            form.setDirection(String.valueOf(DirectionEnum.CHANGE.getValue()));
                        } else if ("上门退".equals(direction)) {
                            form.setDirection(String.valueOf(DirectionEnum.BACK.getValue()));
                        }
                    }
                    if (StringUtils.isNotBlank(bean.getRegionImport())) {
                        String regionId = settlementRegionService.getIdByName(bean.getRegionImport().trim());
                        if (StringUtils.isNotBlank(regionId)) {
                            form.setRegionId(regionId);
                        }
                    }
                    if(StringUtils.isNotBlank(bean.getContainLeftImport())){
                        if("是".equals(bean.getContainLeftImport())){
                            form.setContainLeft("1");
                        } else if("否".equals(bean.getContainLeftImport())){
                            form.setContainLeft("0");
                        }

                    }
                    if(StringUtils.isNotBlank(bean.getContainRightImport())){
                        if("是".equals(bean.getContainLeftImport())){
                            form.setContainRight("1");
                        }else if("否".equals(bean.getContainRight())){
                            form.setContainRight("0");
                        }
                    }
                    if(StringUtils.isNotBlank(bean.getCodImport())){
                        if("是".equals(bean.getCodImport())){
                            form.setCod(String.valueOf(CodEnum.Valid.getState()));
                        }else if("否".equals(bean.getCodImport())){
                            form.setCod(String.valueOf(CodEnum.Invalid.getState()));
                        }
                    }
                    form.setPointLeft(bean.getPointLeft());
                    form.setPointRight(bean.getPointRight());
                    form.setFixWeight(bean.getFixWeight());
                    form.setFirstPrice(bean.getFirstPrice());
                    form.setSecondPrice(bean.getSecondPrice());
                    form.setSupplierCodeImport(bean.getSupplierCodeImport());
                    form.setDirectionImport(bean.getDirectionImport());
                    form.setRegionImport(bean.getRegionImport());
                    form.setContainRightImport(bean.getContainRightImport());
                    form.setContainLeftImport(bean.getContainLeftImport());
                    form.setCodImport(bean.getCodImport());
                    List<String> msgList = validate(form);
                    WeightRangeRule weightRangeRule = convertWeightRangeRule(form);
                    weightRangeRule.setState(StateEnum.Valid.getState());
                    if (msgList == null || msgList.size() == 0) {
                        try {
                            weightRangeService.add(weightRangeRule);
                        } catch (BaseException e) {
                            errMsg.add(e.getErrorMsg());
                            errList.add(weightRangeRule);
                        } catch (Exception e) {

                            errMsg.add(e.getMessage());
                            errList.add(weightRangeRule);

                        }
                    }else{

                        StringBuffer msgStr = new StringBuffer();
                        for (String msg : msgList) {
                            msgStr.append(msg + "||");

                        }
                        msgStr.replace(msgStr.lastIndexOf("||"), msgStr.length(), "");
                        errMsg.add(msgStr.toString());
                        errList.add(weightRangeRule);

                    }
                }
                successNums = list.size() - errList.size();
                totalNums = list.size();

            }
        } catch (Exception e)

        {
            return getFailResult(BaseConstants.ERR_UNKOWN, e.getMessage());
        } finally

        {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }

        String fileKey = null;
        if (errList != null && errList.size() > 0)

        {
            String path = getRealPath("");
            File file = null;
            try {
                path += System.currentTimeMillis() + BaseConstants.DEFAULT_EXPORT_FILE_SUFFIX;
                file = new File(path);
                ExportBuilder builder = new ExportBuilder
                        (WeightRangeImportTemplateBean.class,
                                new WeightRangeParse()
                        );
                ExportFactory factory = ExportFactory.getExportFactory(
                        builder);
                factory.setErrMsgList(errMsg).setDataList(errList).outPut(file);
                fileKey = FileUtils.uploadFile("import/weight/", file.getName(), file);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            } finally {
                if (file != null) {
                    file.delete();
                }
            }
        }

        Map<String, String> returnMap = new HashMap<String, String>();
        returnMap.put("fileKey", fileKey);
        returnMap.put("successNums", String.valueOf(successNums));
        returnMap.put("totalNums", String.valueOf(totalNums));
        return getSuccessResult(returnMap);
    }


}
